#include <iostream>
#include <queue>
#include <vector>
using namespace std;

const int kMaxN = 2e5 + 10;
const int kInf = 1e9;

struct Graph {
  int n;
  vector<pair<int, int>> g[kMaxN];
  int dist[kMaxN];
  queue<int> que;

  void AddEdge(int u, int v, int w) {
    g[u].emplace_back(v, w);
  }

  void Dijkstra(int s = 1) {
    priority_queue<pair<int, int>> pq;

    fill(dist, dist + n + 1, kInf);
    dist[s] = 0;
    pq.emplace(-dist[s], s);
    while (!pq.empty()) {
      int d = -pq.top().first, u = pq.top().second;

      pq.pop();
      if (dist[u] != d) {
        continue;
      }
      for (const pair<int, int> &e : g[u]) {
        int v = e.first;

        if (dist[v] > d + e.second) {
          dist[v] = d + e.second;
          pq.emplace(-dist[v], v);
        }
      }
    }
  }
};

int h[kMaxN];
int main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  Graph graph;
  int m;

  cin >> graph.n >> m;
  for (int i = 1; i <= graph.n; i++) {
    cin >> h[i];
  }
  for (int i = 0; i < m; i++) {
    int u, v;

    cin >> u >> v;
    if (h[u] < h[v]) {
      swap(u, v);
    }
    graph.AddEdge(u, v, 0);
    graph.AddEdge(v, u, h[u] - h[v]);
  }
  graph.Dijkstra(1);
  int ans = 0;
  for (int i = 1; i <= graph.n; i++) {
    ans = max(ans, h[1] - h[i] - graph.dist[i]);
  }
  cout << ans << "\n";
  return 0;
}